JBoss Community Archive (Read Only)

PicketBox

based Identity Store

Introduction

This sectoin covers how to configure PicketBox to use a JPA-based Identity Store.

Make sure that your application is properly configured with Java Persistence API.

The only thing you need to know is how to configure this store with PicketBox. Its usage is the same as described by the Identity Management section. Remember that the most important component when working with PicketBox's Identity Management features is the Identity Manager. The stores only define which repository should be used and how to connect and integrate with them.
For more information about how to manage your users, roles, groups and related information using the Identity Manager, check the Identity Management section.

Default Domain Model Overview

The PicketLink IDM provides a built-in schema based on the domain model described on the Identity Management section. This schema is mapped to some JPA entities that can be used and configured in your application to quickly start using a database as an identity store.

images/author/download/attachments/55476742/jpa_based_default_model.png

Here is some description about these JPA Entities:

  • IdentityObject: Stores all IdentityType instances such as User, Agent Group and Role.

  • IdentityObjectAttributes: Stores the attributes for a specific IdentityObject instance.

  • CredentialObject: Stores all types of credentials.

  • CredentialObjectAttributes: Stores the attributes for a specific CredentialObject instance.

  • MembershipObject: Stores the relationship between User, Group and Role instances (all IdentityObject instances).

Configuration

JPA Persistence Unit example

Example of persistence.xml configured with the JPA Entities
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
	version="1.0">
	<persistence-unit name="picketbox-testing-pu"
		transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>

        <class>org.picketlink.idm.jpa.schema.IdentityObject</class>
        <class>org.picketlink.idm.jpa.schema.CredentialIdentityObject</class>        
        <class>org.picketlink.idm.jpa.schema.CredentialObjectAttribute</class>        
        <class>org.picketlink.idm.jpa.schema.MembershipObject</class>
        <class>org.picketlink.idm.jpa.schema.IdentityObjectAttribute</class>

		<properties>
			<property name="hibernate.connection.url" value="jdbc:h2:mem:test" />
			<property name="hibernate.connection.driver_class" value="org.h2.Driver" />
			<property name="hibernate.connection.username" value="sa" />
			<property name="hibernate.connection.password" value="" />
			<property name="hibernate.hbm2ddl.auto" value="update" />
		</properties>
	</persistence-unit>
</persistence>

Configuring PicketBox

To configure this store you need to use the Configuration API to define some specific configuration.

Configuring the JPA-based Identity Store
ConfigurationBuilder builder = new ConfigurationBuilder();

// configure the JPA identity store
builder.identityManager().jpaStore();

PicketBoxManager picketBoxManager = // create and start the manager

IdentityManager identityManager = picketBoxManager.getIdentityManager();

// now you can play with the Identity Manager instance using the JPA Identity Store.

You may notice that we did not specify any specific configuration about how the configured store should get a valid JPA EntityManager instance, join your transactions, etc.

Using the EntityManagerPropagationContext to provide a EntityManager instance

When using this store you only need to provide the JPA EntityManager using a ThreadLocal by using the org.picketbox.core.identity.jpa.EntityManagerPropagationContext class.

Here is a complete example that demonstrates how to configure and use this store using a JUnit test case.

    private EntityManagerFactory entityManagerFactory;

    /**
     * <p>
     * Tests if the authentication performs successfully when provided a valid {@link UsernamePasswordCredential}.
     * </p>
     *
     * @throws AuthenticationException
     */
    @Test
    public void testUserNamePasswordCredential() throws AuthenticationException {
        ConfigurationBuilder builder = new ConfigurationBuilder();

        // configure the JPA identity store
        builder.identityManager().jpaStore();

        PicketBoxManager picketBoxManager = createManager(builder);

        UserContext authenticatingUser = new UserContext();

        authenticatingUser.setCredential(new UsernamePasswordCredential("admin", "admin"));

        // let's authenticate the user
        UserContext authenticatedUser = picketBoxManager.authenticate(authenticatingUser);

        assertNotNull(authenticatedUser);
        assertTrue(authenticatedUser.isAuthenticated());
        assertRoles(authenticatedUser);
        assertGroups(authenticatedUser);
    }


    @Before
    public void onSetup() throws Exception {
        this.entityManagerFactory = Persistence.createEntityManagerFactory("picketbox-testing-pu");

        EntityManager entityManager = this.entityManagerFactory.createEntityManager();

        entityManager.getTransaction().begin();
        
        // sets the current JPA EntityManager instance                
        EntityManagerPropagationContext.set(entityManager);    
    }

    @After
    public void onFinish() throws Exception {
        EntityManager entityManager = EntityManagerPropagationContext.get();

        entityManager.flush();
        entityManager.getTransaction().commit();
        entityManager.close();
        
        // clear the context. Do not forget to do that.
        EntityManagerPropagationContext.clear();
        this.entityManagerFactory.close();
    }

The example above uses the onSetup() and onFinish() methods to populate and clear the EntityManagerPropagationContext, respectively. 

Usually you'll put the EntityManagerPropagationContext logic inside a Servlet Filter (if you're configuring a web application) or using some kind of interceptor component like the ones provided by CDI or the EJB specifications.

Implementing different strategies to lookup the EntityManager

If you do not want use the EntityManagerPropagationContext with its ThreadLocal strategy to lookup for the EntityManager instance, you can provide a custom implementation for the org.picketbox.core.identity.jpa.EntityManagerLookupStrategy class.

The example bellow demonstrates how a implementation looks like when trying to provide a EntityManager instance in a CDI environment.

@ApplicationScoped
public class CDIEntityManagerLookupStrategy extends EntityManagerLookupStrategy {
    
    @Inject
    private Instance<EntityManager> entityManager;

    @Override
    protected EntityManager lookupEntityManager() {
        EntityManager entityManager = null;

        try {
            entityManager = this.entityManager.get();
        } catch (Exception e) {
            // handle when no entitymanager instance is found
        }

        return entityManager;
    }
}
To use your custom implementation you only need to specify it when building the PicketBox configuration.

    @Inject
    private CDIEntityManagerLookupStrategy entityManagerLookupStrategy;


    @Produces
    public ConfigurationBuilder createConfiguration() {
        ConfigurationBuilder builder = new ConfigurationBuilder();

        builder
            .identityManager()
                .jpaStore()
                    .entityManagerLookupStrategy(this.entityManagerLookupStrategy);

        return builder;
    }
JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-11 12:16:27 UTC, last content change 2013-01-10 18:15:09 UTC.